using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MinesweeperGame
{
    /// <summary>
    /// 自动演示类，实现扫雷游戏的自动演示功能
    /// </summary>
    public class AutoDemo
    {
        /// <summary>
        /// 游戏引擎引用
        /// </summary>
        private GameEngine gameEngine;

        /// <summary>
        /// 是否正在运行演示
        /// </summary>
        public bool IsRunning { get; private set; }

        /// <summary>
        /// 是否暂停
        /// </summary>
        public bool IsPaused { get; private set; }

        /// <summary>
        /// 演示速度
        /// </summary>
        public DemoSpeed Speed { get; set; }

        /// <summary>
        /// 演示操作列表
        /// </summary>
        private List<DemoOperation> operations;

        /// <summary>
        /// 当前操作索引
        /// </summary>
        private int currentOperationIndex;

        /// <summary>
        /// 取消令牌源
        /// </summary>
        private CancellationTokenSource cancellationTokenSource;

        /// <summary>
        /// 演示操作完成事件
        /// </summary>
        public event EventHandler<DemoOperationEventArgs> OperationCompleted;

        /// <summary>
        /// 演示完成事件
        /// </summary>
        public event EventHandler<DemoCompletedEventArgs> DemoCompleted;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="gameEngine">游戏引擎</param>
        public AutoDemo(GameEngine gameEngine)
        {
            this.gameEngine = gameEngine;
            this.operations = new List<DemoOperation>();
            this.Speed = DemoSpeed.Medium;
            this.IsRunning = false;
            this.IsPaused = false;
        }

        /// <summary>
        /// 开始演示
        /// </summary>
        public async void StartDemo()
        {
            if (IsRunning) return;

            IsRunning = true;
            IsPaused = false;
            currentOperationIndex = 0;
            cancellationTokenSource = new CancellationTokenSource();

            try
            {
                await RunDemoAsync(cancellationTokenSource.Token);
            }
            catch (OperationCanceledException)
            {
                // 演示被取消
            }
            finally
            {
                IsRunning = false;
                IsPaused = false;
            }
        }

        /// <summary>
        /// 停止演示
        /// </summary>
        public void StopDemo()
        {
            if (!IsRunning) return;

            cancellationTokenSource?.Cancel();
            IsRunning = false;
            IsPaused = false;
            currentOperationIndex = 0;
        }

        /// <summary>
        /// 暂停演示
        /// </summary>
        public void PauseDemo()
        {
            if (IsRunning && !IsPaused)
            {
                IsPaused = true;
            }
        }

        /// <summary>
        /// 继续演示
        /// </summary>
        public void ResumeDemo()
        {
            if (IsRunning && IsPaused)
            {
                IsPaused = false;
            }
        }

        /// <summary>
        /// 单步演示
        /// </summary>
        public void StepDemo()
        {
            if (!IsRunning || IsPaused)
            {
                ExecuteNextOperation();
            }
        }

        /// <summary>
        /// 异步运行演示
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        private async Task RunDemoAsync(CancellationToken cancellationToken)
        {
            while (IsRunning && !cancellationToken.IsCancellationRequested)
            {
                if (IsPaused)
                {
                    await Task.Delay(100, cancellationToken);
                    continue;
                }

                // 检查游戏状态，允许在NotStarted和Playing状态下运行
                if (gameEngine.State != GameState.NotStarted && gameEngine.State != GameState.Playing)
                {
                    break;
                }

                // 分析游戏板并生成操作
                if (operations.Count == 0 || currentOperationIndex >= operations.Count)
                {
                    AnalyzeBoard();
                }

                if (operations.Count == 0)
                {
                    // 无法找到安全操作，随机选择一个
                    var randomCell = GetRandomUnrevealedCell();
                    if (randomCell != null)
                    {
                        operations.Add(new DemoOperation
                        {
                            Row = randomCell.Row,
                            Col = randomCell.Col,
                            Type = OperationType.Reveal,
                            Reason = "随机选择"
                        });
                    }
                    else
                    {
                        break;
                    }
                }

                // 执行下一个操作
                ExecuteNextOperation();

                // 等待指定时间
                int delay = GetDelayForSpeed(Speed);
                await Task.Delay(delay, cancellationToken);
            }

            // 演示完成
            OnDemoCompleted();
        }

        /// <summary>
        /// 分析游戏板
        /// </summary>
        private void AnalyzeBoard()
        {
            operations.Clear();
            currentOperationIndex = 0;

            var board = gameEngine.Board;
            if (board == null) return;

            // 1. 寻找明显安全的方块
            var safeCells = FindSafeCells();
            foreach (var cell in safeCells)
            {
                operations.Add(new DemoOperation
                {
                    Row = cell.Row,
                    Col = cell.Col,
                    Type = OperationType.Reveal,
                    Reason = "明显安全"
                });
            }

            // 2. 寻找明显的地雷
            var mineCells = FindMineCells();
            foreach (var cell in mineCells)
            {
                operations.Add(new DemoOperation
                {
                    Row = cell.Row,
                    Col = cell.Col,
                    Type = OperationType.Flag,
                    Reason = "明显是地雷"
                });
            }

            // 3. 寻找快速展开机会
            var quickRevealCells = FindQuickRevealCells();
            foreach (var cell in quickRevealCells)
            {
                operations.Add(new DemoOperation
                {
                    Row = cell.Row,
                    Col = cell.Col,
                    Type = OperationType.QuickReveal,
                    Reason = "快速展开"
                });
            }

            // 4. 逻辑推理
            var logicOperations = FindLogicOperations();
            operations.AddRange(logicOperations);
        }

        /// <summary>
        /// 寻找明显安全的方块
        /// </summary>
        /// <returns>安全方块列表</returns>
        private List<Cell> FindSafeCells()
        {
            var safeCells = new List<Cell>();
            var board = gameEngine.Board;

            for (int row = 0; row < board.Rows; row++)
            {
                for (int col = 0; col < board.Cols; col++)
                {
                    var cell = board.Cells[row, col];
                    if (cell.IsRevealed && cell.AdjacentMineCount > 0)
                    {
                        var adjacentCells = board.GetAdjacentCells(row, col);
                        var flaggedCount = adjacentCells.Count(c => c.IsFlagged);
                        var unrevealedCount = adjacentCells.Count(c => !c.IsRevealed && !c.IsFlagged);

                        // 如果标记的地雷数量等于数字，则剩余的都是安全的
                        if (flaggedCount == cell.AdjacentMineCount && unrevealedCount > 0)
                        {
                            var safeAdjacentCells = adjacentCells.Where(c => !c.IsRevealed && !c.IsFlagged);
                            safeCells.AddRange(safeAdjacentCells);
                        }
                    }
                }
            }

            return safeCells.Distinct().ToList();
        }

        /// <summary>
        /// 寻找明显的地雷
        /// </summary>
        /// <returns>地雷方块列表</returns>
        private List<Cell> FindMineCells()
        {
            var mineCells = new List<Cell>();
            var board = gameEngine.Board;

            for (int row = 0; row < board.Rows; row++)
            {
                for (int col = 0; col < board.Cols; col++)
                {
                    var cell = board.Cells[row, col];
                    if (cell.IsRevealed && cell.AdjacentMineCount > 0)
                    {
                        var adjacentCells = board.GetAdjacentCells(row, col);
                        var flaggedCount = adjacentCells.Count(c => c.IsFlagged);
                        var unrevealedCount = adjacentCells.Count(c => !c.IsRevealed && !c.IsFlagged);

                        // 如果未揭开的方块数量等于剩余地雷数量，则都是地雷
                        // 剩余地雷数量 = 总地雷数量 - 已标记的地雷数量
                        if (unrevealedCount == (cell.AdjacentMineCount - flaggedCount) && unrevealedCount > 0)
                        {
                            var mineAdjacentCells = adjacentCells.Where(c => !c.IsRevealed && !c.IsFlagged);
                            mineCells.AddRange(mineAdjacentCells);
                        }
                    }
                }
            }

            return mineCells.Distinct().ToList();
        }

        /// <summary>
        /// 寻找快速展开机会
        /// </summary>
        /// <returns>可以快速展开的方块列表</returns>
        private List<Cell> FindQuickRevealCells()
        {
            var quickRevealCells = new List<Cell>();
            var board = gameEngine.Board;

            for (int row = 0; row < board.Rows; row++)
            {
                for (int col = 0; col < board.Cols; col++)
                {
                    var cell = board.Cells[row, col];
                    // 只有已揭开的数字方块才能使用快速展开
                    if (cell.IsRevealed && cell.AdjacentMineCount > 0)
                    {
                        var adjacentCells = board.GetAdjacentCells(row, col);
                        var flaggedCount = adjacentCells.Count(c => c.IsFlagged);
                        var unrevealedCount = adjacentCells.Count(c => !c.IsRevealed && !c.IsFlagged);

                        // 如果标记的地雷数量等于数字，且还有未揭开的方块，则可以快速展开
                        if (flaggedCount == cell.AdjacentMineCount && unrevealedCount > 0)
                        {
                            quickRevealCells.Add(cell);
                        }
                    }
                }
            }

            return quickRevealCells.Distinct().ToList();
        }

        /// <summary>
        /// 寻找逻辑推理操作
        /// </summary>
        /// <returns>逻辑操作列表</returns>
        private List<DemoOperation> FindLogicOperations()
        {
            var operations = new List<DemoOperation>();
            var board = gameEngine.Board;

            // 这里可以实现更复杂的逻辑推理算法
            // 例如：约束满足问题求解、概率分析等

            return operations;
        }

        /// <summary>
        /// 获取随机未揭开的方块
        /// </summary>
        /// <returns>随机方块</returns>
        private Cell GetRandomUnrevealedCell()
        {
            var board = gameEngine.Board;
            var unrevealedCells = new List<Cell>();

            for (int row = 0; row < board.Rows; row++)
            {
                for (int col = 0; col < board.Cols; col++)
                {
                    var cell = board.Cells[row, col];
                    if (!cell.IsRevealed && !cell.IsFlagged)
                    {
                        unrevealedCells.Add(cell);
                    }
                }
            }

            if (unrevealedCells.Count == 0) return null;

            var random = new Random();
            return unrevealedCells[random.Next(unrevealedCells.Count)];
        }

        /// <summary>
        /// 执行下一个操作
        /// </summary>
        private void ExecuteNextOperation()
        {
            if (currentOperationIndex >= operations.Count) return;

            var operation = operations[currentOperationIndex];
            
            // 触发操作开始事件（不执行操作，让UI先处理虚拟鼠标移动）
            OnOperationCompleted(operation);
            
            currentOperationIndex++;
        }

        /// <summary>
        /// 根据速度获取延迟时间
        /// </summary>
        /// <param name="speed">演示速度</param>
        /// <returns>延迟时间（毫秒）</returns>
        private int GetDelayForSpeed(DemoSpeed speed)
        {
            switch (speed)
            {
                case DemoSpeed.Slow: return 2000;    // 慢速：2秒
                case DemoSpeed.Medium: return 1200;  // 中速：1.2秒
                case DemoSpeed.Fast: return 800;     // 快速：0.8秒
                default: return 1200;
            }
        }

        /// <summary>
        /// 触发操作完成事件
        /// </summary>
        /// <param name="operation">完成的操作</param>
        protected virtual void OnOperationCompleted(DemoOperation operation)
        {
            OperationCompleted?.Invoke(this, new DemoOperationEventArgs(operation));
        }

        /// <summary>
        /// 触发演示完成事件
        /// </summary>
        protected virtual void OnDemoCompleted()
        {
            DemoCompleted?.Invoke(this, new DemoCompletedEventArgs());
        }
    }

    /// <summary>
    /// 演示操作类
    /// </summary>
    public class DemoOperation
    {
        /// <summary>
        /// 行索引
        /// </summary>
        public int Row { get; set; }

        /// <summary>
        /// 列索引
        /// </summary>
        public int Col { get; set; }

        /// <summary>
        /// 操作类型
        /// </summary>
        public OperationType Type { get; set; }

        /// <summary>
        /// 操作原因
        /// </summary>
        public string Reason { get; set; }
    }

    /// <summary>
    /// 演示操作完成事件参数
    /// </summary>
    public class DemoOperationEventArgs : EventArgs
    {
        /// <summary>
        /// 完成的操作
        /// </summary>
        public DemoOperation Operation { get; }

        public DemoOperationEventArgs(DemoOperation operation)
        {
            Operation = operation;
        }
    }

    /// <summary>
    /// 演示完成事件参数
    /// </summary>
    public class DemoCompletedEventArgs : EventArgs
    {
    }
} 